<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>GoJS Buttons -- Northwoods Software</title>
  <!-- Copyright 1998-2016 by Northwoods Software Corporation. -->
    <script src="go.js"></script>
  <script src="goIntro.js"></script>
</head>
<body onload="goIntro()">
<div id="container" class="container-fluid">
<div id="content">

<h2>Buttons</h2>
<p>
For your convenience we have defined several <a>Panel</a>s for common uses.
These include "Button", "TreeExpanderButton", "SubGraphExpanderButton", "PanelExpanderButton", and "ContextMenuButton".
</p>
<p>
These predefined panels can be used as if they were <a>Panel</a>-derived classes in calls to <a>GraphObject.make</a>.
They are implemented as simple visual trees of <a>GraphObject</a>s in <a>Panel</a>s,
with pre-set properties and event handlers.
</p>
<p>
You can see a copy of their definitions in this file:
<a href="../extensions/Buttons.js">Buttons.js</a>.
</p>

<h3>General Buttons</h3>
<p>
The most general kind of predefined <a>Panel</a> is "Button".
</p>
<pre data-language="javascript" id="button">
  diagram.initialContentAlignment = go.Spot.Center;

  diagram.nodeTemplate =
    $(go.Node, "Auto",
      { locationSpot: go.Spot.Center },
      $(go.Shape, "Rectangle",
        { fill: "gold" }),
      $(go.Panel, "Vertical",
        { margin: 3 },
        $("Button",
          { margin: 2,
            click: incrementCounter },
          $(go.TextBlock, "Click me!")),
        $(go.TextBlock,
          new go.Binding("text", "clickCount",
                         function(c) { return "Clicked " + c + " times."; }))
      )
    );

  function incrementCounter(e, obj) {
    var node = obj.part;
    var data = node.data;
    if (data) {
      node.diagram.startTransaction("clicked");
      var old = data.clickCount;
      data.clickCount++;
      node.diagram.model.raiseDataChanged(data, "clickCount", old, data.clickCount);
      node.diagram.commitTransaction("clicked");
    }
  }

  diagram.model = new go.GraphLinksModel(
    [ { clickCount: 0 } ]);
</pre>
<script>goCode("button", 600, 150)</script>

<h3>TreeExpanderButtons</h3>
<p>
It is common to want to expand and collapse subtrees.
It is easy to let the user control this by adding an instance of the "TreeExpanderButton" to your node template.
</p>
<pre data-language="javascript" id="treeExpanderButton">
  diagram.initialContentAlignment = go.Spot.Center;

  diagram.nodeTemplate =
    $(go.Node, "Spot",
      $(go.Panel, "Auto",
        $(go.Shape, "Rectangle",
          { fill: "gold" }),
        $(go.TextBlock, "Click small button\nto collapse/expand subtree",
          { margin: 5 })
      ),
      $("TreeExpanderButton",
        { alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Top },
        { visible: true })
    );

  diagram.layout = $(go.TreeLayout, { angle: 90 });

  diagram.model = new go.GraphLinksModel(
    [ { key: 1 },
      { key: 2 } ],
    [ { from: 1, to: 2 } ] );
</pre>
<script>goCode("treeExpanderButton", 600, 200)</script>

<h3>SubGraphExpanderButtons</h3>
<p>
It is also common to want to expand and collapse groups containing subgraphs.
You can let the user control this by adding an instance of the "SubGraphExpanderButton" to your group template.
</p>
<pre data-language="javascript" id="subgraphExpanderButton">
  diagram.initialContentAlignment = go.Spot.Center;

  diagram.groupTemplate =
    $(go.Group, "Auto",
      $(go.Shape, "Rectangle",
        { fill: "gold" }),
      $(go.Panel, "Vertical",
        { margin: 5,
          defaultAlignment: go.Spot.Left },
        $(go.Panel, "Horizontal",
          $("SubGraphExpanderButton",
            { margin: new go.Margin(0, 3, 5, 0) }),
          $(go.TextBlock, "Group")
        ),
        $(go.Placeholder)
      )
    );

  diagram.model = new go.GraphLinksModel(
    [ { key: 0, isGroup: true },
      { key: 1, group: 0 },
      { key: 2, group: 0 },
      { key: 3, group: 0 } ] );
</pre>
<script>goCode("subgraphExpanderButton", 600, 150)</script>

<h3>PanelExpanderButtons</h3>
<p>
It is common to want to expand and collapse a piece of a node,
thereby showing or hiding details that are sometimes not needed.
It is easy to let the user control this by adding an instance of the "PanelExpanderButton" to your node template.
The second argument to <a>GraphObject.make</a> should be a string that names the element in the node whose
<a>GraphObject.visible</a> property you want the button to toggle.
</p>
<pre data-language="javascript" id="panelExpanderButton">
  diagram.initialContentAlignment = go.Spot.Center;

  diagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape,
        { fill: "gold" }),
      $(go.Panel, "Table",
        { defaultAlignment: go.Spot.Top, defaultColumnSeparatorStroke: "black" },
        $(go.Panel, "Table",
          { column: 0 },
          $(go.TextBlock, "List 1",
            { column: 0, margin: new go.Margin(3, 3, 0, 3),
              font: "bold 12pt sans-serif" }),
          $("PanelExpanderButton", "LIST1",
            { column: 1 }),
          $(go.Panel, "Vertical",
            { name: "LIST1", row: 1, column: 0, columnSpan: 2 },
            new go.Binding("itemArray", "list1"))
        ),
        $(go.Panel, "Table",
          { column: 1 },
          $(go.TextBlock, "List 2",
            { column: 0, margin: new go.Margin(3, 3, 0, 3),
              font: "bold 12pt sans-serif" }),
          $("PanelExpanderButton", "LIST2",
            { column: 1 }),
          $(go.Panel, "Vertical",
            { name: "LIST2", row: 1, column: 0, columnSpan: 2 },
            new go.Binding("itemArray", "list2"))
        )
      )
    );

  diagram.model = new go.GraphLinksModel([
    {
      key: 1,
      list1: [ "one", "two", "three", "four", "five" ],
      list2: [ "first", "second", "third", "fourth" ]
    }
  ]);
</pre>
<script>goCode("panelExpanderButton", 600, 200)</script>

<h3>ContextMenuButtons</h3>
<p>
Although you can implement context menus in any way you choose, it is common to use the predefined "ContextMenuButton".
</p>
<pre data-language="javascript" id="contextMenuButtons">
  diagram.initialContentAlignment = go.Spot.Center;

  diagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape, "Rectangle",
        { fill: "gold" }),
      $(go.TextBlock, "Use ContextMenu!",
        { margin: 5 })
    );

  diagram.nodeTemplate.contextMenu =
    $(go.Adornment, "Vertical",
      $("ContextMenuButton",
        $(go.TextBlock, "Shift Left"),
        { click: function(e, obj) { shiftNode(obj, -20); } }),
      $("ContextMenuButton",
        $(go.TextBlock, "Shift Right"),
        { click: function(e, obj) { shiftNode(obj, +20); } })
    );

  function shiftNode(obj, dist) {
    var adorn = obj.part;
    var node = adorn.adornedPart;
    node.diagram.startTransaction("Shift");
    var pos = node.location.copy();
    pos.x += dist;
    node.location = pos;
    node.diagram.commitTransaction("Shift");
  }

  diagram.model = new go.GraphLinksModel(
    [ { key: 1 } ] );
</pre>
<script>goCode("contextMenuButtons", 600, 150)</script>
<p>
For an example of defining context menus using HTML, see the <a href="../samples/customContextMenu.html">Custom ContextMenu sample</a>.
</p>

<h3>Button Definitions</h3>
<p>
The implementation of all predefined buttons is provided in <a href="../extensions/Buttons.js">Buttons.js</a>
in the Extensions directory.
You may wish to copy and adapt these definitions when creating your own buttons.
</p>
<p>
Those definitions might not be an up-to-date description
of the actual standard button implementations that are in <b>GoJS</b> and used by <a>GraphObject.make</a>.
</p>

</div>
</div>
</body>
</html>
